export class Mind {
  constructor(dom) {
    this.outer = dom;
    this.inner = document.createElement('div');
    // 初始展开的层级（深度）
    this.initialTreeDepth = 2;
    // 平移和缩放
    this.tx = 0;
    this.ty = 0;
    this.scale = 1;
    // 初始化
    this._init();
  }
  _init() {
    this.outer.classList.add('m-outer');
    this.inner.classList.add('m-inner');
    this.outer.appendChild(this.inner);
    this._roam();
  }
  render(ops) {
    const { data, initialTreeDepth } = ops;
    this.initialTreeDepth = initialTreeDepth;
    this.inner.innerHTML = '';
    this._initTransform();
    this._createTree(this.inner, data, 0);
  }
  /**
   * createTree
   * @param {Element} dom
   * @param {Array} arr
   * @param {Number} level
   */
  _createTree(dom, arr = [], level) {
    arr.forEach((item) => {
      const node = document.createElement('section');
      const nodeItem = document.createElement('div');
      const nodeItemLabel = document.createElement('span');

      node.classList.add('node');
      nodeItem.classList.add('node-item');
      nodeItemLabel.classList.add('node-item-label');
      if (level === 0) {
        nodeItem.classList.add('is-root');
      }

      nodeItem.appendChild(nodeItemLabel);
      node.appendChild(nodeItem);
      dom.appendChild(node);

      nodeItemLabel.innerText = item.label;

      if (item.children?.length > 0) {
        // 展开 折叠
        if (level < this.initialTreeDepth) {
          nodeItem.classList.add('is-expand');
        } else {
          nodeItem.classList.add('is-collapse');
        }
        const nodeChildren = document.createElement('div');
        nodeChildren.classList.add('node-children');
        node.appendChild(nodeChildren);
        this._createTree(nodeChildren, item.children, level + 1);
      } else {
        nodeItem.classList.add('is-leaf');
      }

      // 点击: active+折叠+回调
      nodeItemLabel.addEventListener('click', () => {
        // active
        const nodeItemLabelAll =
          this.inner.querySelectorAll('.node-item-label');
        nodeItemLabelAll.forEach((item) => {
          item.classList.remove('is-active');
        });
        nodeItemLabel.classList.add('is-active');
        // 折叠
        if (item.children?.length > 0) {
          nodeItem.classList.toggle('is-expand');
          nodeItem.classList.toggle('is-collapse');
        }
      });
    });
  }
  // 平移和缩放
  _setTransform() {
    this.inner.style.transform = `translate(${this.tx}px, ${this.ty}px) scale(${this.scale})`;
  }
  _initTransform() {
    this.tx = 0;
    this.ty = 0;
    this.scale = 1;
    this._setTransform();
  }
  _roam() {
    this.outer.addEventListener('mousedown', (e) => {
      e.preventDefault();
      // 记录初始值
      const _tx = this.tx;
      const _ty = this.ty;
      const _clientX = e.clientX;
      const _clientY = e.clientY;
      /**
       * @param {MouseEvent} ev
       */
      const move = (ev) => {
        this.tx = ev.clientX - _clientX + _tx;
        this.ty = ev.clientY - _clientY + _ty;
        this._setTransform();
      };
      const up = (ev) => {
        document.removeEventListener('mousemove', move);
        document.removeEventListener('mouseup', up);
      };
      document.addEventListener('mousemove', move);
      document.addEventListener('mouseup', up);
    });
    this.outer.addEventListener('wheel', (e) => {
      e.preventDefault();

      if (e.deltaY < 0) {
        // 向上 放大
        this.scale += 0.05;
      } else {
        // 向下 缩小
        this.scale -= 0.05;
      }
      const min = 0.5;
      const max = 1.5;
      if (this.scale < min) {
        this.scale = min;
      }
      if (this.scale > max) {
        this.scale = max;
      }
      this._setTransform();
    });
  }
}
